using System.Diagnostics;
using System.Drawing.Imaging;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using EzPinyin;
using PaddleOCRSharp;
using SqlSugar;

namespace 三国题库
{
    public partial class Form1 : Form
    {
        public PaddleOCREngine engine = new();
        private List<QuestionDb> questions = new List<QuestionDb>(); // 题库数据
        private Rectangle selectedRegion = Rectangle.Empty; // 用户选定的截屏区域
        // 全局的PaddleOCR引擎

        /// <summary>
        /// 构造函数，初始化Form1，加载题库数据并初始化OCR引擎
        /// </summary>
        public Form1()
        {
            InitializeComponent();
            InitializeOCR();
            LoadSavedRegion(); // 加载之前保存的截屏区域
        }
        /// <summary>
        /// 初始化OCR
        /// </summary>
        private void InitializeOCR()
        {
            OCRModelConfig? config = null;
            OCRParameter oCRParameter = new OCRParameter()
            {
                use_angle_cls = true, // 启用方向分类
                det_db_score_mode = true,
                det_db_thresh = 0.3F, // 检测框阈值
                det_db_box_thresh = 0.6F,
                rec_img_h = 48 // 识别图像高度
            }; engine = new PaddleOCREngine(config, oCRParameter);
        }
        /// <summary>
        /// 从位图中提取文本
        /// </summary>
        /// <param name="bmp">要处理的位图</param>
        /// <returns>提取的文本列表</returns>
        public List<string> ExtractTextFromBitmap(Bitmap bmp)
        {
            try
            {
                var ocrResult = engine.DetectText(bmp);
                return ocrResult.TextBlocks.Select(s => s.Text).ToList();
            }
            catch (Exception ex)
            {
                Debug.WriteLine("图片有问题: " + ex.Message);
                return new List<string>();
            }

        }
        private static double CalculateSimilarity(string str1, string str2)
        {
            int distance = LevenshteinDistance(str1, str2);
            int maxLength = Math.Max(str1.Length, str2.Length);
            return (1 - (double)distance / maxLength) * 100;
        }
        private void button1_Click(object sender, EventArgs e)
        {
            if (selectedRegion == Rectangle.Empty)
            {
                MessageBox.Show("请先设置截屏区域！");
                return;
            }
            try
            {
                // 1. 截取指定区域
                Bitmap clipboardImage = ScreenCapture.CaptureRegion(selectedRegion);
                pictureBox1.Image = clipboardImage;
                Bitmap screenshot = pictureBox1.Image as Bitmap ?? CaptureScreen();
                var str = ExtractTextFromBitmap(screenshot);
                //清空所有Text
                textBox1.Text = "";
                textBox2.Text = "";
                textBox3.Text = "";
                if (radioButton1.Checked)
                {
                    //模式1
                    方法2(str);
                }
                else if (radioButton2.Checked)
                {
                    //模式2
                    SendToAPI(str);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"操作失败: {ex.Message}");
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            添加问题();
        }
        /// <summary>
        /// 清理题库
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            //从数据库中找出问题和答案一模一样的并删除
           List<QuestionDb> s= questions.Distinct().ToList();
            //清空数据库
            SqlSugarContext.DB.Deleteable<QuestionDb>().ExecuteCommand();
            //插入新的题目
            SqlSugarContext.DB.Insertable(s).ExecuteCommand();
            // 显示消息框提示题库已清理
            MessageBox.Show("题库已清理！重复项已移除！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        private Bitmap CaptureScreen()
        {
            Bitmap bmp = new Bitmap(Screen.PrimaryScreen!.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
            Graphics g = Graphics.FromImage(bmp);
            g.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
            return bmp;
        }

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="question">问题</param>
        /// <param name="answer">答案</param>
        /// <param name="minSimilarity">相似率</param>
        /// <returns>列表</returns>
        private List<(QuestionDb, double)> FindSimilarQuestions(string question, double minSimilarity)
        {
            var questions = SqlSugarContext.DB.Queryable<QuestionDb>().ToList();


            List<(QuestionDb, double)> s = questions.Select(q => new { q, Similarity = CalculateSimilarity(question, q.question!) })
                    .Where(x => x.Similarity >= minSimilarity)
                    .OrderByDescending(item => item.Similarity) // 添加这一行进行排序
                    .Select(item => (item.q, item.Similarity))
                    .ToList();
            while (s.Count < 1)
            {
                minSimilarity -= 2;
                s = questions.Select(q => new { q, Similarity = CalculateSimilarity(question, q.question!) })
                    .Where(x => x.Similarity >= minSimilarity)
                    .OrderByDescending(item => item.Similarity) // 添加这一行进行排序
                    .Select(item => (item.q, item.Similarity))
                    .ToList();

            }

            return s;
        }
        private Bitmap GetBitmap(Bitmap original)
        {
            // 创建一个新的 Bitmap 用于存储二值化后的图像
            Bitmap binaryImage = new Bitmap(original.Width, original.Height);

            // 定义阈值 (0 - 255)
            int threshold = 128;

            // 遍历图像的每一个像素
            for (int y = 0; y < original.Height; y++)
            {
                for (int x = 0; x < original.Width; x++)
                {
                    // 获取当前像素的颜色
                    Color pixelColor = original.GetPixel(x, y);

                    // 计算灰度值：使用加权平均法来计算灰度
                    int grayValue = (int)(pixelColor.R * 0.299 + pixelColor.G * 0.587 + pixelColor.B * 0.114);

                    // 根据灰度值进行二值化
                    Color newColor = grayValue > threshold ? Color.White : Color.Black;

                    // 设置对应的像素到二值图像
                    binaryImage.SetPixel(x, y, newColor);
                }
            }

            return binaryImage; // 返回二值化后的图像
        }

        /// 模式2：从题库中查找问题，然后根据答案选项判断
        /// </summary>
        /// <param name="str"></param>
        private void SendToAPI(List<string> str)
        {
            string question = "";
            int n = 0;
        start:
            question += str[n];
            var answer = "";
            var similarQuestions = FindSimilarQuestions(question, 85 - (n * 5));

            if (similarQuestions.Count == 1)
            {
                textBox3.Text = "答案：" + similarQuestions[0].Item1.answer;
                textBox1.Text = "问题：" + similarQuestions[0].Item1.question;
                textBox2.Text = "选项：\r\n" + string.Join("\r\n", str.Skip(n + 1).Select(s => s.Trim()));
            }
            else if (similarQuestions.Count > 1)
            {
                textBox2.Text = "选项：\r\n" + string.Join(";\r\n", str.Skip(n + 1).Select(s => s.Trim()));
                answer = textBox2.Text.Substring(3);
                var answerIndex = similarQuestions.Select(q => new { q, Similarity = CalculateSimilarity(q.Item1.answer, answer) })
                                                 .OrderByDescending(item => item.Similarity)
                                                 .ToList();
                if (answerIndex != null)
                {
                    textBox1.Text = "问题：\r\n" + string.Join("\r\n", similarQuestions.Select((q, i) => $"{i + 1}. {q.Item1.question}"));
                    textBox3.Text = "答案：\r\n" + string.Join("\r\n", similarQuestions.Select(q => q.Item1.answer));
                }
                else
                {
                    // 添加问题();
                }
            }
            else
            {
                if (n < 3)
                {
                    n++;
                    goto start;
                }
                // 添加问题();
            }
        }

        private void 方法2(List<string> str)
        {
            string str2 = string.Join(";", str);
            Debug.WriteLine("合并后的文本: " + str2);
            str2 = Regex.Replace(str2, @"[^\w\s\?A-Za-z\.;]", "");
            Match questionMatch = Regex.Match(str2, @"^([^A-Z]*)\??", RegexOptions.Singleline);
            string question = questionMatch.Success ? questionMatch.Groups[1].Value.Trim() : "";
            var minSimilarity = 60;
            if (question == "")
            {
                question = str2;
                minSimilarity = 10;

            }
            Debug.WriteLine("提取的问题: " + question);
            string answerPart = str2.Substring(question.Length).TrimStart('?', ';', ' ');
            Debug.WriteLine("提取的答案部分: " + answerPart);
            List<string> options = new List<string>();
            MatchCollection optionMatches = Regex.Matches(answerPart, @"([A-D][^\s].*?)(?=[A-D][^\s]|$)", RegexOptions.Singleline);
            foreach (Match match in optionMatches)
            {
                options.Add(match.Value.Trim());
            }
            Debug.WriteLine("提取的答案选项: " + string.Join(", ", options));
            var similarQuestions = FindSimilarQuestions(question, minSimilarity);
            if (options.Count < 2)
            {
                options = str;
            }
            foreach (var q in similarQuestions)
            {
                foreach (var option in options)
                {
                    double similarity = CalculateSimilarity(option, q.Item1.answer);
                    if (similarity > 0)
                    {

                    }
                }
            }



            if (2 > 0)
            {
                //textBox3.Text中显示answerList中所有元素的question和answer
                StringBuilder answerBuilder = new StringBuilder();
                var n = 1;
                foreach (var answer in similarQuestions)
                {
                    answerBuilder.AppendLine("问题" + n + ":" + answer.Item1.question);
                    answerBuilder.AppendLine($"答案{n}:【{answer.Item1.answer}】");
                    answerBuilder.AppendLine();
                    n++;
                }
                textBox3.Text = answerBuilder.ToString();
                textBox1.Text = "问题：" + question;
                textBox2.Text = "选项：\r\n" + string.Join("\r\n", options);
            }
            else
            {
                // MessageBox.Show("未找到相关问题！");
            }
        }
        /// <summary>
        /// 计算编辑距离
        /// </summary>
        /// <param name="s"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public static int LevenshteinDistance(string s, string t)
        {
            if (string.IsNullOrEmpty(s))
            {
                return string.IsNullOrEmpty(t) ? 0 : t.Length;
            }

            if (string.IsNullOrEmpty(t))
            {
                return s.Length;
            }

            int n = s.Length;
            int m = t.Length;
            int[,] d = new int[n + 1, m + 1];

            for (int i = 0; i <= n; d[i, 0] = i++) ;
            for (int j = 0; j <= m; d[0, j] = j++) ;

            for (int i = 1; i <= n; i++)
            {
                for (int j = 1; j <= m; j++)
                {
                    int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
                    d[i, j] = Math.Min(
                        Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
                        d[i - 1, j - 1] + cost);
                }
            }
            return d[n, m];
        }
        // 修改 FindAnswerFromDB 方法
        public string FindAnswerFromDB(string question)
        {
            var allQuestions = SqlSugarContext.DB.Queryable<QuestionDb>().ToList();
            int minDistance = int.MaxValue;
            QuestionDb? bestMatch = null;

            foreach (var q in allQuestions)
            {
                int distance = LevenshteinDistance(question, q.question ?? string.Empty);
                if (distance < minDistance)
                {
                    minDistance = distance;
                    bestMatch = q;
                }
            }

            return bestMatch != null ? bestMatch.answer : string.Empty;
        }
        /// <summary>
        private void 添加问题()
        {
            string question = textBox1.Text;
            string answer = textBox2.Text;

            try
            {
                question = textBox1.Text.Substring(3);
            }
            catch (ArgumentOutOfRangeException)
            {
                // 可以在这里记录日志或者给出提示信息
                MessageBox.Show("问题文本长度不足，不进行截取操作。");
            }

            try
            {
                answer = textBox2.Text.Substring(3);
            }
            catch (ArgumentOutOfRangeException)
            {
                MessageBox.Show("答案文本长度不足，不进行截取操作。");
            }

            var options = answer.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

            Form form2 = new Form
            {
                Width = 400,
                Height = 150,
                StartPosition = FormStartPosition.CenterScreen,
                FormBorderStyle = FormBorderStyle.FixedSingle,
                MaximizeBox = false,
                MinimizeBox = false,
                ShowIcon = false,
                TopMost = true,
                Text = $"添加问题{question}"
            };

            Label label2 = new Label
            {
                Text = "正确答案：",
                AutoSize = true,
                Location = new Point(10, 10)
            };
            form2.Controls.Add(label2);

            ComboBox comboBox1 = new ComboBox
            {
                Location = new Point(10, 30),
                Width = 280,
                DropDownStyle = ComboBoxStyle.DropDown
            };
            foreach (var item in options)
            {
                comboBox1.Items.Add(item);
            }
            comboBox1.Items.AddRange(options);
            form2.Controls.Add(comboBox1);

            Button button3 = new Button
            {
                Text = "确定",
                Location = new Point(10, 70),
                Width = 75,
                Height = 25,
                DialogResult = DialogResult.OK
            };

            button3.Click += (s, e) =>
            {
                var selectedOption = comboBox1.SelectedItem?.ToString() ?? "未选择";
                var newAnswer = selectedOption;
                var newIndexes = PinyinHelper.GetInitial(question);

                var newQuestion2 = new QuestionDb { answer = newAnswer, indexes = newIndexes, question = question };

                var sane = SqlSugarContext.DB.Queryable<QuestionDb>().Where(q => q.question == newQuestion2.question).ToList();
                if (sane.Count > 0)
                {
                    DialogResult result = MessageBox.Show("已存在相同的问题，是否覆盖？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (result == DialogResult.Yes)
                    {
                        sane.First().answer = newAnswer;
                        var s1 = SqlSugarContext.DB.Updateable(sane).ExecuteCommand();
                        MessageBox.Show("覆盖成功！" + s1);
                    }
                }
                else
                {
                    SqlSugarContext.DB.Insertable(newQuestion2).ExecuteCommand();
                    MessageBox.Show("添加成功！");
                }

                //json = JsonSerializer.Serialize(questions);
                form2.Close();
            };

            form2.Controls.Add(button3);
            form2.ShowDialog();
        }

        /// <summary>
        /// Question类，表示题库中的一个问题
        /// </summary>
        /// 
        public class Question
        {
            [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
            public int id { get; set; }
            public string answer { get; set; } = string.Empty;
            public string indexes { get; set; } = string.Empty;
            public string question { get; set; } = string.Empty;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            Form form2 = new Form
            {
                Width = 400,
                Height = 150,
                StartPosition = FormStartPosition.CenterScreen,
                FormBorderStyle = FormBorderStyle.FixedSingle,
                MaximizeBox = false,
                MinimizeBox = false,
                ShowIcon = false,
                TopMost = true,
                Text = "删除问题"
            };
            ComboBox comboBox1 = new ComboBox
            {
                Location = new Point(10, 30),
                Width = 280,
                DropDownStyle = ComboBoxStyle.DropDownList
            };
            var s=ExtractQuestions(textBox3.Text);
            comboBox1.Items.AddRange(s.ToArray());
            // 处理数据，将每一项转换为 "id:question" 格式的字符串
            //var processedList = answerList.Select(x => $"{x.Item1.id}:{x.Item1.question}").ToList();

            // 将处理后的字符串列表设置为 ComboBox 的数据源
            // comboBox1.DataSource = processedList;


            //comboBox1.Items.AddRange(s.ToArray());
            form2.Controls.Add(comboBox1);

            Button button3 = new Button
            {
                Text = "确定",
                Location = new Point(10, 70),
                Width = 75,
                Height = 25,
                DialogResult = DialogResult.OK
            };

            button3.Click += (s, e) =>
            {
                //点击确定后需要先获取combobox选中的项目，然后提取ID，并从题库中删除
                string selectedItem = comboBox1.SelectedItem?.ToString() ?? string.Empty;
                var b = SqlSugarContext.DB.Deleteable<QuestionDb>().Where(q => q.question == selectedItem).ExecuteCommand();
                if (b>0)
                {
                    MessageBox.Show("删除成功！");
                }
                else
                {
                    MessageBox.Show("删除失败！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

            };

            form2.Controls.Add(button3);
            form2.ShowDialog();
            questions = SqlSugarContext.DB.Queryable<QuestionDb>().ToList();


        }

        private void button5_Click(object sender, EventArgs e)
        {
            using (var regionForm = new RegionSelectorForm())
            {
                if (regionForm.ShowDialog() == DialogResult.OK)
                {
                    selectedRegion = regionForm.SelectedRegion;
                    SaveRegion(); // 保存区域设置
                    MessageBox.Show($"区域已设定: {selectedRegion}");
                }
            }
        }
        // 加载保存的截屏区域
        private void LoadSavedRegion()
        {
            if (Properties.Settings.Default.SelectedRegion != Rectangle.Empty)
            {
                selectedRegion = Properties.Settings.Default.SelectedRegion;
            }
        }

        // 保存截屏区域到设置
        private void SaveRegion()
        {
            Properties.Settings.Default.SelectedRegion = selectedRegion;
            Properties.Settings.Default.Save();
        }

        private void textBox4_TextChanged(object sender, EventArgs e)
        {
            // 转义特殊字符
            var escape = new Func<string, string>(s => s.Replace("'", "''")
                                                   .Replace("[", "[[]")
                                                   .Replace("%", "[%]"));

            // 构建动态过滤条件
            var filters = new List<string>();
            string Fint = textBox4.Text.Trim();
            if (!string.IsNullOrEmpty(Fint))
            {
                filters.Add($"question like '%{escape(Fint)}%'");
            }
            // 构建查询语句
            var answerList = questions.Where(q => q.indexes.ToUpper().Contains(Fint.ToUpper())).ToList();
            var answerBuilder = new StringBuilder();
            var n = 1;
            foreach (var answer in answerList)
            {
                answerBuilder.AppendLine("问题" + n + ":" + answer.question);
                answerBuilder.AppendLine($"答案{n}:【{answer.answer}】");
                answerBuilder.AppendLine();
                n++;
            }
            textBox3.Text = answerBuilder.ToString();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

            questions = SqlSugarContext.DB.Queryable<QuestionDb>().ToList();
        }
        static List<string> ExtractQuestions(string text)
        {
            List<string> questions = new List<string>();
            // 正则表达式匹配问题
            Regex regex = new Regex(@"问题\d*:(.*?)\r?\n");
            MatchCollection matches = regex.Matches(text);
            foreach (Match match in matches)
            {
                if (match.Success && match.Groups.Count > 1)
                {
                    questions.Add(match.Groups[1].Value.Trim());
                }
            }
            return questions;
        }
    }

    public class ScreenCapture
    {
        // 截取指定区域
        public static Bitmap CaptureRegion(Rectangle region)
        {
            Bitmap bitmap = new Bitmap(region.Width, region.Height);
            using (Graphics g = Graphics.FromImage(bitmap))
            {
                g.CopyFromScreen(region.Location, Point.Empty, region.Size);
            }
            return bitmap;
        }
        public static Bitmap PreprocessImage(Bitmap original)
        {
            // 转换为灰度图像
            Bitmap grayImage = new Bitmap(original.Width, original.Height);
            using (Graphics g = Graphics.FromImage(grayImage))
            {
                ColorMatrix colorMatrix = new ColorMatrix(
                    new float[][]
                    {
                new float[] {0.299f, 0.299f, 0.299f, 0, 0},
                new float[] {0.587f, 0.587f, 0.587f, 0, 0},
                new float[] {0.114f, 0.114f, 0.114f, 0, 0},
                new float[] {0, 0, 0, 1, 0},
                new float[] {0, 0, 0, 0, 1}
                    });
                ImageAttributes attributes = new ImageAttributes();
                attributes.SetColorMatrix(colorMatrix);
                g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
                    0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);
            }

            // 二值化（阈值处理）
            Bitmap binaryImage = new Bitmap(grayImage.Width, grayImage.Height);
            for (int y = 0; y < grayImage.Height; y++)
            {
                for (int x = 0; x < grayImage.Width; x++)
                {
                    Color pixel = grayImage.GetPixel(x, y);
                    int avg = (pixel.R + pixel.G + pixel.B) / 3;
                    binaryImage.SetPixel(x, y, avg > 150 ? Color.White : Color.Black);
                }
            }

            return binaryImage;
        }
    }

}